package test.demo;

import cn.hutool.core.io.FileUtil;
import tech.waterism.modelbase.PredictBase;
import tech.waterism.modelbase.PredictResult;
import com.alibaba.fastjson.JSON;

import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 系统模型集成
 * 前期影响雨量Pa推求：Pa(t+1) = K * (Pa(t) + P(t))
 * 一般用于日尺度
 * 适用于白石水库(一层模式)
 *
 * @author 曹玉璞
 * @version 1.0
 */
public class PA extends PredictBase {

    private double PA;  // 当前的前期影响雨量状态
    private double PAM;  // 土含上限
    private Date[] TM;  //每个时间节点
    private double[] PP;  //时段降雨量
    private double K;

    public PA(Map<String, String> data) {
        super();
        // 初始化参数以及模型状态
        PA = Double.parseDouble(data.get("PA"));
        PAM = Double.parseDouble(data.get("PAM"));
        TM = JSON.parseObject(data.get("dt"), Date[].class);
        PP = JSON.parseObject(data.get("rain"), double[].class);
        K = Double.parseDouble(data.get("K"));
    }

    public Map<String, double[]> PAmodel() {

        int Pnum = PP.length;  //降雨的时段长度

        // 初始化随时间改变的状态变量
        double[] PAP = new double[Pnum + 1];  // 前期影响雨量状态
        double[] RP = new double[Pnum];  // 逐时段产流量（假拟，方便系统中构建模型）

        PAP[0] = PA;  //初始状态赋值
            
        for (int i = 0; i <= Pnum - 1; i++){
            Map<String, Double> WMap = calculatePA(PP[i], PAP[i]);  //开始计算蒸发
            PAP[i + 1] = WMap.get("PAP");
            RP[i] = WMap.get("R");
        }

        Map<String, double[]> simulationResult = new HashMap<>();

        simulationResult.put("PAP", PAP);
        simulationResult.put("RunoffSim", RP);
        return simulationResult;
    }

    private Map<String, Double> calculatePA(double PP, double PAP) {
        double R = 0.0;
        PAP = K * (PAP + PP);
        if (PAP > PAM){
            PAP = PAM;
        }
        
        Map<String, Double> WResult = new HashMap<>();
        WResult.put("PAP", PAP);
        WResult.put("R", R);  //逐时段产流量
        return WResult;
    }

    private List<String> toStringList(double[] array0) {
        String[] array = new String[array0.length];
        for (int i = 0; i < array.length; i++) {
            array[i] = String.valueOf(array0[i]);
        }
        return Arrays.asList(array);
    }

    @Override
    public void init() {

    }

    @Override
    public PredictResult predict() {
        PredictResult result = new PredictResult();
        Map<String, double[]> map = PAmodel();
        double[][] RSim = new double[1][];
        //流域地表产流
        RSim[0] = map.get("RunoffSim");

        //流域面积总产流 R
        result.setRunoffSim(map.get("RunoffSim"));

        result.setRSim(RSim);

        // 更新状态
        List<String> PA = toStringList(map.get("PAP"));


        Map<String, List<String>> status = new HashMap<>();
        //前期影响雨量
        status.put("PA", PA);

        result.setNewStatus(status);

        return result;
    }

    public static void main(String[] args) {
        // 从文件读取真实数据
//        String dataStr = FileUtil.readString("D:\\Desktop\\chn_dllg_21401550-plcd9-1748053028650.txt", "utf-8");
        String dataStr = "{\"K\":\"0.8\"," +
                "\"PAM\":\"160\"," +
                "\"PA\":\"158\"," +
                "\"dt\":\"[\\\"2020-06-01 08:00:00\\\",\\\"2020-06-02 08:00:00\\\"]\"," +
                "\"rain\":\"[50,0]\"}";
        Map<String, String> data = JSON.parseObject(dataStr, Map.class);

        PA model = new PA(data);
        PredictResult result = model.predict();
        System.out.println(result);
    }
}
